﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Cci;
using PartialExpressionCompleter.Util;

namespace PartialExpressionCompleter.Experiment
{
    class MethodCallFinder : CodeTraverser
    {
        private List<Tuple<IMethodDefinition, IMethodCall>> calls =
            new List<Tuple<IMethodDefinition, IMethodCall>>();

        public MethodCallFinder()
        {
            this.TraverseIntoMethodBodies = true;
            this.PreorderVisitor = new PreVisitor(this);
            this.PostorderVisitor = new PostVisitor(this);
        }

        private IMethodDefinition currentMethod = null;
        private class PreVisitor : CodeVisitor
        {
            private readonly MethodCallFinder mcf;
            internal PreVisitor(MethodCallFinder mcf) { this.mcf = mcf; }

            public override void Visit(IMethodBody methodBody)
            {
                mcf.currentMethod = methodBody.MethodDefinition;
            }
            public override void Visit(IMethodCall methodCall)
            {
                mcf.calls.Add(mcf.currentMethod.PairWith(methodCall));
            }
        }
        private class PostVisitor : CodeVisitor
        {
            private readonly MethodCallFinder mcf;
            internal PostVisitor(MethodCallFinder mcf) { this.mcf = mcf; }

            public override void Visit(IMethodBody methodBody)
            {
                mcf.currentMethod = null;
            }
        }


        public static List<Tuple<IMethodDefinition, IMethodCall>> GetAllCalls(
                IAssembly unit)
        {
            var mcf = new MethodCallFinder();
            mcf.Traverse(unit);
            return mcf.calls;
        }
    }
}
